package com.pds.utils;

import com.pds.common.utils.StringUtils;
import com.pds.system.service.ISysConfigService;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Author fafa
 * @Date 2024/5/28 15:05
 * @Version 1.0
 * @Description 密码校验工具类
 */

@Component
public class PwdCheckUtil {


    private static final int maxSeqCnt = 4;
    private static final String seqStr[] = {"qwertyuiopasdfghjklzxcvbnm",
            "QWERYUIOPASDFGHJKLZXCVBNM",
            "1234567890-=",
            "qwertyuiop[]\\asdfghjkl;'zxcvbnm,./",
    };


    @Resource
    private ISysConfigService configServiceIns;


    private static ISysConfigService configService;

    @PostConstruct
    public void init() {
        configService = this.configServiceIns;
    }

    /**
     * 校验密码
     *
     * @return
     */
    public static boolean checkPwd(String pwd) {
        return isValid(pwd) && !isKeyboardConsecutive(pwd) && checkSystemConfig(pwd);

    }


    /**
     * 密码由四种元素组成（数字、大写字母、小写字母、特殊字符），且必须包含全部四种元素；密码长度大于等于8个字符，小于20位。
     */
    public static boolean isValid(String password) {
        // 正则表达式的内容如下:
        // ^(?![0-9A-Za-z]+$)(?![0-9A-Z\W]+$)(?![0-9a-z\W]+$)(?![A-Za-z\W]+$)[0-9A-Za-z~!@#$%^&*()__+`\-={}|[\]\\:";'<>?,./]{8,}$
        // 在 Java 中使用，需要转义；转义后的结果如下。
        String pattern = "^(?![0-9A-Za-z]+$)(?![0-9A-Z\\W]+$)(?![0-9a-z\\W]+$)(?![A-Za-z\\W]+$)[0-9A-Za-z~!@#$%^&*()_+`\\-={}|\\[\\]\\\\:\";'<>?,./]{8,20}$";
        return Pattern.matches(pattern, password);
    }

    /**
     * 是否为键盘连续字符
     *
     * @param pwd
     * @return
     */
    public static boolean isKeyboardConsecutive(String pwd) {
        int size = pwd.length();
        String temp = "";
        int offset = 0;
        //提前定义的连续字符串
        for (String s : seqStr) {
            offset = 0;
            //直接从最大允许的字符开始截取字符
            for (int i = maxSeqCnt; i <= size; i++) {
                temp = pwd.substring(offset++, i);
                //出现连续字符，直接返回true
                if (s.contains(temp)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查系统配置的弱密码
     *
     * @param pwd
     * @return
     */
    private static boolean checkSystemConfig(String pwd) {
        String weakPwd = configService.selectConfigByKey("weak_pwd");
        if (StringUtils.isBlank(weakPwd)) {
            return true;
        }

        List<String> list = Arrays.asList(weakPwd.split(","));

        for (String str : list) {
            if (pwd.toLowerCase().contains(str.trim().toLowerCase())) {
                return false;
            }
        }
        return true;
    }

}
